/**
  ******************************************************************************
  * @file    bsp_spi.h
  * @author  Yun
  * @version V1.0.0
  * @date    2025-02-14
  * @brief   SPI总线硬件抽象层
  * @license EULA (End User License Agreement)
  *          Copyright (c) 2025 星瑜科技自动化 Co., Ltd. All rights reserved.
  ******************************************************************************
  */

#ifndef FRAMEWORK_BSP_SPI_H
#define FRAMEWORK_BSP_SPI_H

/*---------------------- 依赖组件 ----------------------*/
#include "bsp_gpio.h"          ///< GPIO硬件抽象层依赖
#include "stm32f1xx_hal_spi.h" ///< STM32 HAL库SPI模块
#include "spi_interface.h"

/*---------------------- 硬件配置 ----------------------*/
/**
  * @brief  SPI硬件配置结构体
  * @note   包含完整的SPI外设物理层配置参数
  */
typedef struct Spi_Hw_Cfg {
    char*                   pcName;  ///< 设备名称
    Gpio_Hw_Cfg_TypeDef     stCLK;   ///< SCK引脚配置（时钟信号）
    Gpio_Hw_Cfg_TypeDef     stMOSI;  ///< MOSI引脚配置（主出从入）
    Gpio_Hw_Cfg_TypeDef     stMISO;  ///< MISO引脚配置（主入从出）
    Gpio_Hw_Cfg_TypeDef     stNSS;   ///< 硬件NSS引脚配置（可选）
    Gpio_Hw_Cfg_TypeDef     stCS;    ///< 软件CS引脚配置（用户控制）
    SPI_HandleTypeDef       stHSpi;  ///< HAL库SPI控制句柄
}Spi_Hw_Cfg_TypeDef;

/*---------------------- 硬件操作API ----------------------*/
/**
  * @brief  初始化SPI总线接口
  * @param  pSpiHwCfg SPI硬件配置指针
  * @retval BSP_Status_TypeDef
  * @note   自动配置GPIO复用功能并启用时钟
  */
uint8_t Bsp_Spi_Init(const void* pSpiHwCfg);

/**
  * @brief  同步数据发送函数
  * @param  pSpiHwCfg   SPI硬件配置指针
  * @param  pu8TxData   发送缓冲区指针
  * @param  u16Len      数据长度（字节）
  * @param  u32TimeOut  操作超时时间（ms）
  * @retval BSP_Status_TypeDef
  * @warning 禁止在中断上下文中调用
  */
uint8_t Bsp_Spi_Transmit(const void* pSpiHwCfg, uint8_t* pu8TxData,
                         uint16_t u16Len, uint32_t u32TimeOut);

/**
  * @brief  同步数据接收函数
  * @param  pSpiHwCfg   SPI硬件配置指针
  * @param  pu8RxData   接收缓冲区指针
  * @param  u16Len      预期接收长度（字节）
  * @param  u32TimeOut  操作超时时间（ms）
  * @retval BSP_Status_TypeDef
  */
uint8_t Bsp_Spi_Receive (const void* pSpiHwCfg, uint8_t* pu8RxData,
                         uint16_t u16Len, uint32_t u32TimeOut);

/**
  * @brief  全双工数据交换
  * @param  pSpiHwCfg   SPI硬件配置指针
  * @param  pu8TxData   发送缓冲区指针
  * @param  pu8RxData   接收缓冲区指针
  * @param  u16Len      数据长度（字节）
  * @param  u32TimeOut  操作超时时间（ms）
  * @retval BSP_Status_TypeDef
  */
uint8_t Bsp_Spi_TransmitReceive(const void* pSpiHwCfg, uint8_t* pu8TxData,
                                uint8_t* pu8RxData, uint16_t u16Len,
                                uint32_t u32TimeOut);

/**
  * @brief  片选信号手动控制
  * @param  pSpiHwCfg   SPI硬件配置指针
  * @param  u8State     目标状态（GPIO_PIN_SET/GPIO_PIN_RESET）
  * @retval BSP_Status_TypeDef
  * @note   需在SPI配置中启用软件NSS模式
  */
uint8_t Bsp_Spi_ControlCS(const void* pSpiHwCfg, uint8_t u8State);

/**
  * @brief  SPI标准接口实例
  * @note   通过此实例访问所有SPI操作接口
  */
extern Spi_Interface_TypeDef stBspSpiInterface;

#endif /* FRAMEWORK_BSP_SPI_H */
